Over-the-Air NVIDIA Jetson - RAUC Bring-up and Yocto Integration

From RidgeRun Developer Wiki

Follow Us On Twitter LinkedIn Email Share this page




NVIDIA partner logo NXP partner logo







RAUC on NVIDIA Jetson: Bring-up and Yocto Integration

This page documents the base integration required to get RAUC built into a Jetson image and running correctly on target.

It covers:

  • Adding meta-rauc
  • Enabling RAUC in the distro
  • Installing RAUC configuration through rauc-conf
  • Ensuring the kernel command line exposes the active slot
  • Fixing the initial RAUC service startup problems
  • Verifying that RAUC is operational on the device

Assumptions

This page assumes:

  • You are using OE4T / tegra-demo-distro
  • You already have a working Jetson image build environment
  • You are targeting a Jetson platform such as p3737-0000-p3701-0005

Adding meta-rauc to tegra-demo-distro

Adding the Layer

The meta-rauc layer was added to the build by extending bblayers.conf:

conf/bblayers.conf

BBLAYERS += "${TOPDIR}/../layers/meta-rauc"

Verification:

bitbake-layers show-layers | grep rauc

Enabling RAUC in the Distro

DISTRO_FEATURES

RAUC must be explicitly enabled:

conf/local.conf

DISTRO_FEATURES:append = " rauc"

Image Installation

If the image does not already pull RAUC indirectly:

IMAGE_INSTALL:append = " rauc"

RAUC Configuration (rauc-conf)

Why rauc-conf

From scarthgap onward, RAUC configuration files are installed by the rauc-conf recipe, not by rauc itself.

This allows:

  • Architecture-independent RAUC binaries
  • Machine-specific configuration handling

Files Installed

The following files were provided in the BSP layer:

meta-tegrademo/recipes-core/rauc/rauc-conf/files/
├── system.conf
└── ca.cert.pem

system.conf Used

[system]
compatible=jetson-agx-orin
bootloader=noop
statusfile=/var/lib/rauc/status

[keyring]
path=/etc/rauc/ca.cert.pem

[slot.rootfs.0]
device=/dev/mmcblk0p1
type=ext4
bootname=A

[slot.rootfs.1]
device=/dev/mmcblk0p2
type=ext4
bootname=B

Important decisions:

  • bootloader=noop is required because Jetson does not use a supported RAUC bootloader backend at the initial bring-up stage
  • Slots are mapped manually to eMMC partitions

Kernel Command Line Requirements

RAUC requires two kernel parameters to identify the active slot:

  • root=
  • rauc.slot=

Example Working cmdline

root=/dev/mmcblk0p1 rauc.slot=A

This was verified on target using:

cat /proc/cmdline

Without these parameters, RAUC fails with:

  • "Could not find any root device or rauc slot information in /proc/cmdline"

Fixing the RAUC Service Startup

Initial Failure

The RAUC systemd service initially failed with errors such as:

  • No bootloader selected
  • Unsupported bootloader
  • Cannot determine slot state

Root Causes Identified

  1. Missing or invalid bootloader= in system.conf
  2. Missing root= and rauc.slot= in kernel cmdline
  3. Missing RAUC status directory

Required Runtime Fixes

On target:

mkdir -p /var/lib/rauc
chmod 700 /var/lib/rauc

Then restart the service:

systemctl restart rauc.service

Successful State

systemctl status rauc.service

Shows:

  • Service active and running
  • Booted slot correctly detected (rootfs.0 / A)

Verifying RAUC Operation

RAUC Status

rauc status

Expected output:

  • Booted slot detected
  • Slot layout visible
  • Warnings about primary slot are expected with noop bootloader

Slot Marking

rauc status mark-good booted

Note:

With bootloader=noop, slot activation is not persisted across reboot. This is a known and accepted limitation at this stage.

RAUC A/B Integration via Yocto

Scope

This section documents the exact Yocto-side changes required to reproduce the manual RAUC setup on Jetson AGX Orin, without touching each target manually.

1) Enable RAUC in distro features

Edit `build/conf/local.conf` and ensure this line exists exactly once:

DISTRO_FEATURES:append = " rauc"

2) Sync the project CA certificate into rauc-conf overlay

Copy your real CA (not RAUC Test CA) into the layer override location:

cp -f openssl-ca/dev/ca.cert.pem \
  layers/meta-tegrademo/recipes-core/rauc/rauc-conf/files/ca.cert.pem

3) Configure RAUC for custom bootloader backend

Update `layers/meta-tegrademo/recipes-core/rauc/rauc-conf/files/system.conf`:

[system]
compatible=jetson-agx-orin
bootloader=custom
statusfile=/var/lib/rauc/status

[keyring]
path=/etc/rauc/ca.cert.pem

[handlers]
bootloader-custom-backend=/usr/lib/rauc/backend/jetson-extlinux

[slot.rootfs.0]
device=/dev/mmcblk0p1
type=ext4
bootname=A

[slot.rootfs.1]
device=/dev/mmcblk0p2
type=ext4
bootname=B

4) Add Yocto recipe for the custom RAUC backend

Create `layers/meta-tegrademo/recipes-core/rauc/jetson-rauc-backend.bb`:

SUMMARY = "RAUC custom bootloader backend for Jetson extlinux"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420"

FILESEXTRAPATHS:prepend := "${THISDIR}/jetson-rauc-backend/files:"

SRC_URI = "file://jetson-extlinux"

S = "${UNPACKDIR}"

do_install() {
    install -d ${D}/usr/lib/rauc/backend
    install -m 0755 ${UNPACKDIR}/jetson-extlinux ${D}/usr/lib/rauc/backend/jetson-extlinux
}

FILES:${PN} = "/usr/lib/rauc/backend/jetson-extlinux"

5) Add Yocto recipe to create `/var/lib/rauc` at boot

Create recipe `layers/meta-tegrademo/recipes-core/rauc/rauc-tmpfiles.bb`:

SUMMARY = "Create RAUC state directory via systemd-tmpfiles"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420"

FILESEXTRAPATHS:prepend := "${THISDIR}/rauc-tmpfiles/files:"

SRC_URI = "file://rauc.conf"

S = "${UNPACKDIR}"

do_install() {
    install -d ${D}${sysconfdir}/tmpfiles.d
    install -m 0644 ${UNPACKDIR}/rauc.conf ${D}${sysconfdir}/tmpfiles.d/rauc.conf
}

FILES:${PN} = "${sysconfdir}/tmpfiles.d/rauc.conf"

Tmpfiles entry:

d /var/lib/rauc 0700 root root -

6) Ensure image packagegroup pulls RAUC components

The packagegroup should include:

  • rauc
  • jetson-rauc-backend
  • rauc-tmpfiles

Validated Result

At the end of this page, the expected validated state is:

  • RAUC built and installed in the image
  • RAUC service starts correctly
  • Slot A/B layout is visible
  • Kernel cmdline exposes root and slot
  • The system is ready for signed bundle installation